import 'package:built_collection/built_collection.dart';
import 'package:backend.core/core/domain/entities/api/api_money_amount.dart';
import 'package:backend.core/core/domain/entities/web/web_purchase_item.dart';
import 'package:backend.core/core/domain/entities/web/web_transaction.dart';
import 'package:backend.core/core/domain/repositories/web_purchase_item_repository/repository.dart';
import 'package:backend.core/core/domain/repositories/web_transaction_repository/repository.dart';
import 'package:equatable/equatable.dart';
import 'package:backend.purchases/domain/helpers/api/create_api_money_amount_from_internal_one.dart';

part 'entities.dart';

abstract class GetWebTransactionHistory {
  Future<BuiltList<WebTransactionHistoryItem>> call({
    required String userId,
  });
}

class GetWebTransactionHistoryImpl implements GetWebTransactionHistory {
  GetWebTransactionHistoryImpl({
    required WebTransactionRepository webTransactionRepository,
    required WebPurchaseItemRepository webPurchaseItemRepository,
    required CreateApiMoneyAmountFromInternalOne createApiMoneyAmountFromInternalOne,
  })  : _webTransactionRepository = webTransactionRepository,
        _webPurchaseItemRepository = webPurchaseItemRepository,
        _createApiMoneyAmountFromInternalOne = createApiMoneyAmountFromInternalOne;

  final WebTransactionRepository _webTransactionRepository;
  final WebPurchaseItemRepository _webPurchaseItemRepository;
  final CreateApiMoneyAmountFromInternalOne _createApiMoneyAmountFromInternalOne;

  @override
  Future<BuiltList<WebTransactionHistoryItem>> call({
    required String userId,
  }) async {
    final futureResults = await Future.wait([
      _webPurchaseItemRepository.findAllPurchaseItems(),
      _webTransactionRepository.findUserTransactions(
        userId: userId,
      ),
    ]);

    var i = 0;
    final purchaseItems = futureResults[i++] as BuiltList<WebPurchaseItem>;
    final userTransactions = futureResults[i++] as BuiltList<WebTransaction>;

    final purchaseItemMap = <String, WebPurchaseItem>{};

    for (final purchaseItem in purchaseItems) {
      purchaseItemMap[purchaseItem.sku] = purchaseItem;
    }

    final userTransactionHistory = userTransactions.map((transaction) {
      final purchaseItem = purchaseItemMap[transaction.purchaseItemSku]!;

      final apiAmount = _createApiMoneyAmountFromInternalOne(
        moneyAmount: transaction.amount,
      );

      return WebTransactionHistoryItem(
        purchaseItem: purchaseItem,
        amount: apiAmount,
        transactionTime: transaction.time,
      );
    }).toList();

    userTransactionHistory.sort((first, second) {
      return second.transactionTime.compareTo(first.transactionTime);
    });

    return userTransactionHistory.toBuiltList();
  }
}
